package com.hudson.plugin.server.hibernateDB.internal.domain.dao;

import com.hudson.plugin.server.hibernateDB.domain.dao.HudsonsDAOInterface;
import com.hudson.plugin.server.hibernateDB.internal.domain.entity.HudsonsEntity;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import java.util.ArrayList;
import java.util.List;

/**
 * A data access object (DAO) providing persistence and search support for
 * Hudsons entities. Transaction control of the save(), update() and delete()
 * operations can directly support Spring container-managed transactions or they
 * can be augmented to handle user-managed Spring transactions. Each of these
 * methods provides additional information for how to configure it for the
 * desired type of transaction control.
 *
 * @author MyEclipse Persistence Tools
 * @see .Hudsons
 */

public class HudsonsDAO extends HibernateDaoSupport implements HudsonsDAOInterface {
    private static final Logger log = LoggerFactory.getLogger(HudsonsDAO.class);

    protected void initDao() {
        // do nothing
    }

    public void save(HudsonsEntity transientInstance) {
        log.debug("saving Hudsons instance");
        try {
            getHibernateTemplate().save(transientInstance);
            log.debug("save successful");
        } catch (RuntimeException re) {
            log.error("save failed", re);
            throw re;
        }
    }

    public void delete(HudsonsEntity persistentInstance) {
        log.debug("deleting Hudsons instance");
        try {
            getHibernateTemplate().delete(persistentInstance);
            log.debug("delete successful");
        } catch (RuntimeException re) {
            log.error("delete failed", re);
            throw re;
        }
    }

    public HudsonsEntity findById(Integer id) {
        log.debug("getting Hudsons instance with id: " + id);
        try {
            HudsonsEntity instance = (HudsonsEntity) getHibernateTemplate().load(HudsonsEntity.class,
                    id);
            return instance;
        } catch (RuntimeException re) {
            log.error("get failed", re);
            throw re;
        }
    }

    public List findByExample(HudsonsEntity instance) {
        log.debug("finding Hudsons instance by example");
        try {
            List results = getHibernateTemplate().findByExample(instance);
            log.debug("find by example successful, result size: "
                    + results.size());

            if (results == null) {
                return new ArrayList();
            }

            return results;
        } catch (RuntimeException re) {
            log.error("find by example failed", re);
            throw re;
        }
    }

    public List findByProperty(String propertyName, Object value) {
        log.debug("finding Hudsons instance with property: " + propertyName
                + ", value: " + value);
        try {
            String queryString = "from HudsonsEntity as model where model."
                    + propertyName + " = ?";
            List results = getHibernateTemplate().find(queryString, value);
            if (results == null) {
                return new ArrayList();
            }
            return results;
        } catch (RuntimeException re) {
            log.error("find by property name failed", re);
            throw re;
        }
    }

    public List findByUrl(Object url) {
        return findByProperty(URL, url);
    }

    public List findByDescription(Object description) {
        return findByProperty(DESCRIPTION, description);
    }

    public List findBySlaves(Object slaves) {
        return findByProperty(SLAVES, slaves);
    }

    public List findAll() {
        log.debug("finding all Hudsons instances");
        try {
            String queryString = "from HudsonsEntity";
            List results = getHibernateTemplate().find(queryString);
            if (results == null) {
                return new ArrayList();
            }
            return results;
        } catch (RuntimeException re) {
            log.error("find all failed", re);
            throw re;
        }
    }

    public HudsonsEntity merge(HudsonsEntity detachedInstance) {
        log.debug("merging Hudsons instance");
        try {
            HudsonsEntity result = (HudsonsEntity) getHibernateTemplate().merge(
                    detachedInstance);
            log.debug("merge successful");
            return result;
        } catch (RuntimeException re) {
            log.error("merge failed", re);
            throw re;
        }
    }

    public void attachDirty(HudsonsEntity instance) {
        log.debug("attaching dirty Hudsons instance");
        try {
            getHibernateTemplate().saveOrUpdate(instance);
            log.debug("attach successful");
        } catch (RuntimeException re) {
            log.error("attach failed", re);
            throw re;
        }
    }

    public void attachClean(HudsonsEntity instance) {
        log.debug("attaching clean Hudsons instance");
        try {
            getHibernateTemplate().lock(instance, LockMode.NONE);
            log.debug("attach successful");
        } catch (RuntimeException re) {
            log.error("attach failed", re);
            throw re;
        }
    }

    public static HudsonsDAOInterface getFromApplicationContext(ApplicationContext ctx) {
        return (HudsonsDAOInterface) ctx.getBean("HudsonsDAO");
    }


    public List<Integer> findHudsonsEntity(String url) {
        log.debug("finding Builds By ProjectId And BuildNumber");
        try {
            Query query = this.getSession().createQuery("select h.id from HudsonsEntity h where h.url =:url");
            query.setParameter("url", url.trim());
            List<Integer> hudsonsIds = query.list();
            if (hudsonsIds == null) {
                return new ArrayList();
            }
            return hudsonsIds;
        } catch (RuntimeException re) {
            log.error("finding Builds By ProjectId And BuildNumber failed", re);
            throw re;
        }
    }
}